package com.example.capsule_netty.controller;

import com.example.capsule_netty.bean.ChatRecordBean;
import com.example.capsule_netty.bean.FileBean;
import com.example.capsule_netty.bean.MessageBean;
import com.example.capsule_netty.bean.UserInfoBean;
import com.example.capsule_netty.impl.ChatRecordServiceImpl;
import com.example.capsule_netty.service.GroupMessageService;
import com.example.capsule_netty.service.OneToOneMessageService;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.io.*;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
 * @Author: zhuzhiming
 * @Date: 2022/5/3 23:07
 */
@RestController
@Slf4j
public class MessageController {


    @Autowired
    GroupMessageService groupMessageService;

    @Autowired
    ChatRecordServiceImpl chatRecordService;

    @Autowired
    OneToOneMessageService oneToOneMessageService;

    @GetMapping("/getGroupMessages/{roomName}")
    public String getMessages(@PathVariable String roomName) {
        return groupMessageService.getMessages(roomName);
    }

    @PostMapping("/uploadImage")
    public void uploadImage(@RequestBody String requestBody) {
        MessageBean  messageBean = new Gson().fromJson(requestBody,MessageBean.class);
        if (messageBean.isOneToOne()) {
            oneToOneMessageService.saveMessage(messageBean);
        } else {
            groupMessageService.saveMessage(messageBean);
        }

    }

    @PostMapping("/getImage")
    @ResponseBody
    public String getImage(@RequestBody String requestBody) {
        MessageBean  messageBean = new Gson().fromJson(requestBody,MessageBean.class);
        if (messageBean == null || messageBean.getFilePath() == null) {
            return new Gson().toJson(new MessageBean());
        }
        byte[] data = null;
        try {
            FileInputStream inputStream = new FileInputStream(messageBean.getFilePath());
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            data = new byte[inputStream.available()];
            bufferedInputStream.read(data);
            bufferedInputStream.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        byte[] encode;
        encode = Base64.getEncoder().encode(data);
        String bytes = new String(encode);

        messageBean = new MessageBean();
        messageBean.setContent(bytes);
        return new Gson().toJson(messageBean);

    }


    @PostMapping("/getFile")
    @ResponseBody
    public String getFile(@RequestBody String requestBody) {
        MessageBean  messageBean = new Gson().fromJson(requestBody,MessageBean.class);
        if (messageBean == null || messageBean.getFilePath() == null) {
            return new Gson().toJson(new MessageBean());
        }
        byte[] data = null;
        String filePath = messageBean.getFilePath();
        if (!new File(filePath.substring(0, filePath.lastIndexOf("/"))).exists()) {
            new File(filePath.substring(0, filePath.lastIndexOf("/"))).mkdirs();
        }
        try {
            FileInputStream inputStream = new FileInputStream(messageBean.getFilePath());
            data = new byte[inputStream.available()];
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            bufferedInputStream.read(data);
            bufferedInputStream.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        byte[] encode;
        encode = Base64.getEncoder().encode(data);
        String bytes = new String(encode);

        messageBean = new MessageBean();
        messageBean.setContent(bytes);
        return new Gson().toJson(messageBean);

    }


    @PostMapping("searchChatRecord")
    public String searchChatRecord(@RequestBody String message) {

        MessageBean messageBean = new Gson().fromJson(message, MessageBean.class);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.should(QueryBuilders.matchQuery("content", messageBean.getContent()));
        boolQuery.should(QueryBuilders.matchQuery("senderId", messageBean.getContent()));
        boolQuery.should(QueryBuilders.matchQuery("roomName", messageBean.getContent()));
        boolQuery.should(QueryBuilders.matchQuery("senderName", messageBean.getContent()));
        boolQuery.should(QueryBuilders.matchQuery("sendTime", messageBean.getContent()));
        searchSourceBuilder.query(boolQuery);
        searchSourceBuilder.fetchSource(new String[]{"field", "roomName", "senderId", "senderName", "sendTime", "content"}, new String[]{});
        searchSourceBuilder.from(0).size(1000);
        SearchResponse response = chatRecordService.search(messageBean.getField().toLowerCase(), searchSourceBuilder);
        List<ChatRecordBean> chatRecordBeanList = new ArrayList<>();
        for (SearchHit hit : response.getHits()) {
            ChatRecordBean chatRecordBean = new Gson().fromJson(hit.getSourceAsString(), ChatRecordBean.class);
            chatRecordBeanList.add(chatRecordBean);
        }
        return new Gson().toJson(chatRecordBeanList);
    }

    @PostMapping("getRecentMessage")
    public String getRecentMessage(@RequestBody MessageBean messageBean) {
        return groupMessageService.getRecentMessage(messageBean);
    }


    @GetMapping("getOneToOneMessages/{roomName}")
    public String getOneToOneMessages(@PathVariable String roomName) {
        return oneToOneMessageService.getMessages(roomName);
    }

    @GetMapping("updateMessageStatus/{roomName}")
    public String updateMessageStatus(@PathVariable String roomName) {
        return oneToOneMessageService.updateMessageStatus(roomName);
    }

}
